home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
awe2-0_1.lha
/
awe2-0.1
/
Src
/
RCS
/
HardwareContext.cc,v
< prev
next >
Wrap
Text File
|
1989-06-21
|
9KB
|
459 lines
head 3.3;
branch ;
access ;
symbols ;
locks grunwald:3.3; strict;
comment @@;
3.3
date 89.06.21.10.14.37; author grunwald; state Exp;
branches ;
next 3.2;
3.2
date 89.02.20.15.34.57; author grunwald; state Exp;
branches ;
next 3.1;
3.1
date 88.12.20.13.48.49; author grunwald; state Exp;
branches ;
next 1.3;
1.3
date 88.10.30.13.04.28; author grunwald; state Exp;
branches ;
next 1.2;
1.2
date 88.09.28.22.13.25; author grunwald; state Exp;
branches ;
next 1.1;
1.1
date 88.09.18.16.42.23; author grunwald; state Exp;
branches ;
next ;
desc
@@
3.3
log
@*** empty log message ***
@
text
@// This may look like C code, but it is really -*- C++ -*-
//
// Copyright (C) 1988 University of Illinois, Urbana, Illinois
//
// written by Dirk Grunwald (grunwald@@cs.uiuc.edu)
//
#include "HardwareContext.h"
#include "CpuMultiplexor.h"
#include "Thread.h"
#include "assert.h"
#include <stream.h>
//
// Many machines have the same (or very similar) stack format.
// The 68K & 32K are examples of such machines.
//
// The const *registers* defines the number of additional longwords
// needed on the stack past the last frame pointer. This value needs
// to jibe with the one in HardwareContext-<arch>.s.
//
#ifdef mc68000
static const int registerQuads = (56 + 96)/4;
typedef long Quad;
#endif
#ifdef ns32000
static const int registerQuads = 15;
typedef long Quad;
#endif
const long MagicStackMarker = 0x464f4f20; // this says 'FOO '
HardwareContext::HardwareContext (int check, unsigned size)
{
checkStackLimits = check;
saved_fp = 0;
saved_sp = 0;
stackBase = 0;
stackEnd = 0;
stackMax = 0;
stackSize = 0;
stackCheck = 0;
stackMallocAt = 0;
if (size > 0) {
stackSize = size;
stackMallocAt = new void *[ stackSize ];
//
// stackBase should point to the first writeable cell of the
// new stack.
//
if (StackGrows == stackGrowsDown) {
stackEnd = stackMallocAt;
stackBase = &stackMallocAt[stackSize-1];
}
else {
stackBase = stackMallocAt;
stackEnd = &stackMallocAt[stackSize-1];
}
}
}
void
HardwareContext::switchContext(HardwareContext *to)
{
if ( checkStackLimits ) { // check old context
checkStack();
}
magicSwitchTo(to);
if ( checkStackLimits ) { // check new context
checkStack();
}
}
void
HardwareContext::stackOverflow()
{
register unsigned depth = stackBase - getSp();
if (stackMax < depth) {
stackMax = depth;
}
if ( stackMax >= stackSize ) {
cerr << "\nStack overflow\n";
cerr << " getSp() = " << hex(long(getSp()));
cerr << " and stackBase = " << hex(long(stackBase)) << "\n";
cerr << *this << "\n";
cerr << "Current task is \n";
cerr << *(CurrentThread());
cerr << "\n";
cerr.flush();
}
assert( stackMax < stackSize );
assert( *stackCheck == MagicStackMarker );
}
#if defined(mc68000) || defined(ns32000)
StackGrowthDirection StackGrows = stackGrowsDown;
void
HardwareContext::buildReturnFrame(void *returnThis, voidFuncP returnAddress)
{
//
// To build a thread, we return to the first address of startOff,
// which will use the current FP & SP to build a local context,
// and then call the user main.
//
// startOff needs to have a valid frame. The return address for this
// frame is NULL, since we never exit procedure startOff.
//
stackCheck = (long *) stackBase;
Quad **stack = (Quad **) stackBase;
*(stack--) = (Quad *) MagicStackMarker;
*(stack--) = 0; // return address
Quad **startOffFp = stack;
*(stack--) = 0; // frame pointer
//
// Construct the stack frame that will be used in procedure startOff.
// startOff needs to know the value for *this*, which is passed in
// as the first parameter. It also gets the back-link FP for the
// last frame (build above).
//
*(stack--) = (Quad *) returnThis;
Quad **nullFp = stack;
*(stack--) = (Quad *) startOffFp; // FP for previous frame
//
// Now build the stack frame that is used to return to startOff
//
*(stack--) = (Quad *) returnAddress;
saved_fp = (void **) stack;
*(stack) = (Quad *) nullFp;
stack -= registerQuads; // number of Quadword registers we are saving
saved_sp = (void **) stack;
}
#endif
void
HardwareContext::classPrintOn(ostream& s)
{
s << "[HardwareContext] Stack spans " << hex(long(stackEnd));
s << " to " << hex(long(stackBase));
s << " used is " << (stackMax) << " of " << stackSize << "\n";
s << "[HardwareContext] fp = " << hex(long(saved_fp));
s << " sp = " << hex(long(saved_sp));
long p = *( (long *) saved_fp );
s << " @@fp = " << hex(p) << "\n";
}
@
3.2
log
@Start using Gnu library heaps for schedulers
@
text
@d23 1
a23 1
static const int registerQuads = 30;
@
3.1
log
@Steay version
@
text
@a31 1
d140 1
a140 1
saved_fp = stack;
d144 1
a144 1
saved_sp = stack;
@
1.3
log
@*** empty log message ***
@
text
@d13 8
a20 1
static const long FOO = 0x464f4f20; // this says 'FOO '
d22 13
d50 1
a50 1
stackMallocAt = new void*[stackSize];
d69 2
a70 24
//
// Check the SP of the current context
//
if (checkStackLimits) {
register unsigned depth = stackBase - getSp();
if (stackMax < depth) {
stackMax = depth;
}
if ( stackMax >= stackSize ) {
cerr << "\nStack overflow\n";
cerr << " getSp() = " << hex(long(getSp()));
cerr << " and stackBase = " << hex(long(stackBase)) << "\n";
cerr << *this << "\n";
if (to != 0) {
cerr << " and were switching to ...\n";
cerr << *to << "\n";
}
cerr << "Current task is \n";
cerr << *(CurrentThread());
cerr << "\n";
cerr.flush();
}
assert( stackMax < stackSize );
assert( *stackCheck == FOO );
d75 2
a76 15
//
// Do all of this again, but now in our new context
//
if (checkStackLimits) {
assert( *stackCheck == FOO );
register unsigned depth = stackBase - getSp();
if (stackMax < depth) {
stackMax = depth;
}
if ( stackMax >= stackSize ) {
cerr << "\nStack overflow\n";
cerr << *this << "\n";
cerr.flush();
}
assert( stackMax < stackSize );
d80 20
a99 8
//
// Many machines have the same (or very similar) stack format.
// The 68K & 32K are examples of such machines.
//
// The const *registers* defines the number of additional longwords
// needed on the stack past the last frame pointer. This value needs
// to jibe with the one in HardwareContext-<arch>.s.
//
a100 9
#ifdef mc68000
static const int registers = 8 + 6 + 8;
#endif
#ifdef ns32000
static const int registers = 7 + 8;
#endif
d118 2
a119 2
void **stack = (void **) stackBase;
*(stack--) = (void *) FOO;
d121 1
a121 1
void **startOffFp = stack;
d131 3
a133 3
*(stack--) = (void *) returnThis;
void **nullFp = stack;
*(stack--) = startOffFp; // FP for previous frame
d139 1
a139 1
*(stack--) = (void *) returnAddress;
d143 2
a144 2
*(stack) = (void *) nullFp;
stack -= registers; // number of longword registers we are saving
d147 1
a147 1
#endif mc68000
@
1.2
log
@*** empty log message ***
@
text
@d1 6
d8 1
a8 1
#include "HardwareCpu.h"
a42 7
}
}
HardwareContext::~HardwareContext()
{
if (stackMallocAt != 0) {
delete stackMallocAt;
@
1.1
log
@Initial revision
@
text
@d7 2
d19 1
d25 4
d31 1
a31 1
stackBase = &stackEnd[stackSize-1];
d35 1
a35 1
stackEnd = &stackBase[stackSize-1];
d73 1
d77 1
d82 1
a95 1
#ifdef mc68000
d97 2
a98 1
// Stack creation routines for the Motorola 68000 family
d100 3
a102 7
StackGrowthDirection StackGrows = stackGrowsDown;
void
HardwareContext::buildReturnFrame(void *returnThis, void *returnAddress)
{
void **stack = stackBase;
a103 14
// To build a thread, we return to the first address of startOff,
// which will use the current FP & SP to build a local context,
// and then call the user main.
//
// startOff needs to have a valid frame
//
*(stack--) = (void *) 0x464f4f20; // this says 'FOO '
//
// This false return address is where I'd go if I left
// procedure 'startOff' (which I never do).
//
*(stack--) = 0; // return address
void **startOffFp = stack;
*(stack--) = 0; // frame pointer
d105 3
a107 6
//
// Construct the stack frame that will be used in procedure startOff.
// We assume that the we need to pass the start-up routine a
// single parameter, which should be the value of *this* for
// the class we're returning to. This is typically a Thread class.
//
d109 3
a111 7
*(stack--) = (void *) returnThis;
void **nullFp = stack;
*(stack--) = startOffFp; // FP for previous frame
//
// Now build the stack frame that is used to return to startOff
//
*(stack--) = returnAddress;
a112 1
saved_fp = stack;
d114 1
a114 2
*(stack) = (void *) nullFp;
stack -= (7 + 6 + 8); // number of longword registers we're saving
a115 7
saved_sp = stack;
stackMax = stackBase - saved_sp;
}
#endif mc68000
#ifdef ns32000
a120 1
void **stack = stackBase;
d126 2
a127 1
// startOff needs to have a valid frame
d129 4
a132 1
*(stack--) = (void *) 0x464f4f20; // this says 'FOO '
a136 1
// Construct the stack frame that will be used in procedure startOff
d138 6
d147 1
a150 2
void *ptr = (void *) returnAddress;
*(stack--) = ptr;
d152 2
d157 1
a157 2
stack -= (7 * 4 + 8 * 4);
d160 1
a160 1
#endif ns32000
d170 2
@